﻿
using NAudio.CoreAudioApi;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Timers;

namespace project1113.SpeechRecoginzer
{
    internal class MicrophoneRecorder
    {
        private WaveInEvent waveIn;
        private Queue<byte> audioDataQueue;
        private int bufferSize;
        private object audioDataLock = new object();
        private WaveFileWriter waveWriter;

        public MicrophoneRecorder(int bufferSize = 1024)
        {
            this.bufferSize = bufferSize;
            audioDataQueue = new Queue<byte>(bufferSize);
        }

        public string StartRecording(string outputFolderPath)
        {
            // 创建文件夹
            if (!Directory.Exists(outputFolderPath))
            {
                Directory.CreateDirectory(outputFolderPath);
            }

            // 生成以当前时间为文件名的随机文件路径
            string outputFilePath = Path.Combine(outputFolderPath, DateTime.Now.ToString("yyyyMMddHHmmss") + ".wav");

            // 删除同名文件（如果存在）
            //if (File.Exists(outputFilePath))
            //{
            //    File.Delete(outputFilePath);
            //}

            waveIn = new WaveInEvent();
            waveIn.WaveFormat = new WaveFormat(44100, 1);
            waveWriter = new WaveFileWriter(outputFilePath, waveIn.WaveFormat);
            waveIn.DataAvailable += WaveIn_DataAvailable;
            waveIn.StartRecording();
            return outputFilePath;
        }

        public void StopRecording()
        {
            waveIn?.StopRecording();
            waveIn?.Dispose(); // 先停止录制，然后再释放资源

            waveWriter?.Dispose();
            waveWriter = null;

            waveIn = null;
        }

        public double GetMicrophoneVolume()
        {
            lock (audioDataLock)
            {
                if (audioDataQueue.Count > 0)
                {
                    byte[] audioData = audioDataQueue.ToArray();
                    double rms = CalculateRMS(audioData);
                    return rms;
                }
            }

            return 0.0; // 或者返回适当的默认值
        }

        private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            try
            {
                waveWriter.Write(e.Buffer, 0, e.BytesRecorded);
                waveWriter.Flush();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception occurred: " + ex.Message);
            }

            lock (audioDataLock)
            {
                foreach (var sample in e.Buffer)
                {
                    audioDataQueue.Enqueue(sample);
                }

                // 如果队列太长，删除最旧的数据以保持缓冲区大小
                while (audioDataQueue.Count > bufferSize)
                {
                    audioDataQueue.Dequeue();
                }
            }
        }

        private double CalculateRMS(byte[] audioData)
        {
            int bytesPerSample = waveIn.WaveFormat.BitsPerSample / 8;
            int sampleCount = audioData.Length / bytesPerSample;
            double sum = 0.0;

            for (int i = 0; i < sampleCount; i++)
            {
                int sampleValue = BitConverter.ToInt16(audioData, i * bytesPerSample);
                double sample = Math.Abs(sampleValue / 1024.0);

                if (sample >= 200)
                {
                    sample = 200;
                }

                sum += sample;
            }

            double mean = sum / sampleCount;
            return mean;
        }
    }
}


